/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package view;

import java.util.Calendar;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.part.ViewPart;

/**
 * Mockup of a browser history view. For now, it's just the sample view
 * generated by PDE.
 */
public class GameView extends ViewPart {
	public GameView() {
	}
	// The width of the image
	private static final int CAVAS_WIDTH = 676;

	// The timer interval in milliseconds
	private static final int TIMER_INTERVAL = 25;

	private boolean isGameStarted;

	private boolean isFrogDead;

	private boolean isReachHome;

	private boolean isDrownInRiver;

	private boolean isFrogonLog = false;

	private boolean isFrogonLog2 = false;


	// The location of the "ball"
	private int homeX = 250;

	private int homeY = 50;
	
	private int riverBand=72;
	
	private int riverWidth=100;

	private int mosquitoX = 320;

	private int mosquitoY = 220;

	private int snakeX = CAVAS_WIDTH - 80;

	private int snakeY = 180;

	private int carX = 20;

	private int carY = 250;

	private int truckX = 20;

	private int truckY = 290;

	private int frogX = 300;

	private int frogY = 340;

	private int logX = CAVAS_WIDTH - 80;

	private int logY = 80;

	private int logX2 = 0;

	private int logY2 = 130;

	// The direction the "ball" is moving
	private int directionX = 5;

	//private int directionY = 5;

	// We draw everything on this canvas
	private Canvas canvas;

	private Image homeImage;

	private Image snakeImage;

	private Image carImage;

	private Image truckImage;

	private Image frogImage;

	private Image mosquitoImage;
	
	//private ImageData logImageData;

	private Image logImage;

	private int frogLiveEnduration = 30;

	private int prolongedEnduration = 10;

	private boolean mosQuitoEated = true;

	private long startMillisTime;

	private long currentMillisTime;

	private String endsupMessage;

	// private ReminderByTimerTimertask reminder;

	public void createPartControl(final Composite parent) {
		isFrogDead = false;
		isReachHome = false;
		mosQuitoEated = false;

		homeImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/home.gif"));
		mosquitoImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/mosquito.gif"));
		snakeImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/snake.gif"));
		carImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/car.gif"));
		truckImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/truck.gif"));
		frogImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/frog.gif"));
	    logImage = new Image(parent.getDisplay(), this.getClass()
				.getResourceAsStream("/images/log.gif"));

		canvas = new Canvas(parent, SWT.NO_BACKGROUND);
		canvas.addMouseListener(new MouseAdapter() {
			public void mouseDoubleClick(MouseEvent e) {
				if (isGameStarted == false)
					isGameStarted = true;
				startMillisTime = Calendar.getInstance().getTimeInMillis();
			}
		});
		canvas.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (e.keyCode == SWT.ARROW_DOWN) {
					frogY = frogY + 10;
				} else if (e.keyCode == SWT.ARROW_UP) {
					if (isFrogonLog == false && isFrogonLog2 == true) {
						frogY = logY + 5;
						if (frogonLog()) {
							isFrogonLog = true;
						} else
							isDrownInRiver = true;
					} else if (isFrogonLog == true && isFrogonLog2 == true) {
						frogY = homeY + 1;
						if (isReachHome()) {
							isReachHome = true;
						} else
							isDrownInRiver = true;
					} else
						frogY = frogY - 10;
				} else if (e.keyCode == SWT.ARROW_LEFT)
					frogX = frogX - 10;
				else if (e.keyCode == SWT.ARROW_RIGHT)
					frogX = frogX + 10;
			}
		});
		canvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				if (isFrogDead == false) {
					final Image image = new Image(parent.getDisplay(), canvas
							.getBounds());
					
					final GC gcImage = new GC(image);
					// Set the back color
					gcImage.setBackground(parent.getDisplay().getSystemColor(
							SWT.COLOR_WHITE));

					// Draw the background
					gcImage.fillRectangle(canvas.getBounds());

					// Set the color of the ball
					gcImage.setBackground(parent.getDisplay().getSystemColor(
							SWT.COLOR_BLUE));

					// Draw the car,snake,mosquito,frog
					currentMillisTime = Calendar.getInstance()
							.getTimeInMillis();
					if (isGameStarted == false)
						gcImage
								.drawText(
										"Press the display anywhere to begin the game.",200, 5, true);
					
					else
						gcImage.drawText("Seconds left:"
								+ (int) (frogLiveEnduration - Math
										.ceil(currentMillisTime
												- startMillisTime) / 1000),
								200, 5, true);

					 gcImage.drawImage(homeImage, homeX, homeY);
					 if (mosQuitoEated==false)
					 gcImage.drawImage(mosquitoImage, mosquitoX, mosquitoY);
					 gcImage.drawImage(snakeImage, snakeX, snakeY);
					 gcImage.drawImage(carImage, carX, carY);
					 gcImage.drawImage(truckImage, truckX, truckY);
										
					 gcImage.fillRectangle(0, riverBand, CAVAS_WIDTH,riverWidth);
					 gcImage.drawImage(logImage, logX, logY);
					 gcImage.drawImage(logImage, logX2, logY2);
					 gcImage.drawImage(frogImage, frogX, frogY);

					// Draw the offscreen buffer to the screen
					event.gc.drawImage(image, 0, 0);

					// Clean up
					image.dispose();
					gcImage.dispose();
					if(isGameStarted){
					if (eatMosquito()) {
						System.out.println("before:" + frogLiveEnduration);
						frogLiveEnduration += prolongedEnduration;
						System.out.println("after:" + frogLiveEnduration);
						mosQuitoEated = true;

					}
					if (isFrogonLog2 == false && isFrogonLog == false
							&& isInRiver()) {
						if (frogonLog2()) {
							isFrogonLog2 = true;
						}
					}
					if (isInRiver() && isFrogonLog2 == false
							&& isFrogonLog == false) {
						isFrogDead = true;
						endsupMessage = new String("frog is drown!Lose!");
					}
					if (isFrogHit()) {
						isFrogDead = true;
						endsupMessage = new String("frog is hit!Lose!");
					}
					if (isReachHome == true) {

						isFrogDead = true;
						endsupMessage = new String("frog reach home!Win!");
					}
					if (isDrownInRiver == true) {
						isFrogDead = true;
						endsupMessage = new String("frog drown in river!Lose!");
					}
					if (isTimeUp()) {
						isFrogDead = true;
						endsupMessage = new String("Time is up!Lose!");
					}

					if (endsupMessage.length() > 0) {
						System.out.println(endsupMessage);
						MessageBox messageBox = new MessageBox(parent
								.getShell(), SWT.ICON_INFORMATION);
						messageBox.setMessage(endsupMessage);
						messageBox.setText(endsupMessage);
						int returnVal = messageBox.open();
					}
				  }
				} else if (isFrogDead == true) {
					System.out.println("isFrogDead==true");
					try {
						parent.dispose();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});

		Runnable runnable = new Runnable() {
			public void run() {
				animate();
				parent.getDisplay().timerExec(TIMER_INTERVAL, this);
			}
		};

		// Launch the timer
		parent.getDisplay().timerExec(TIMER_INTERVAL, runnable);
	}

	public boolean isFrogHit() {
		if ((snakeX < frogX) && (frogX < snakeX + snakeImage.getBounds().width)
				&& (snakeY < frogY)
				&& (frogY < snakeY + snakeImage.getBounds().height)) {
			return true;
		} else if ((Math.abs(snakeX - frogX) < frogImage.getBounds().width)
				&& (Math.abs(frogY - snakeY) < frogImage.getBounds().height)) {
			return true;
		} else if ((carX < frogX)
				&& (frogX < carX + carImage.getBounds().width)
				&& (frogY > carY)
				&& (frogY < carY + carImage.getBounds().height)) {
			return true;
		} else if ((frogX < carX)
				&& (carX < frogX + frogImage.getBounds().width)
				&& (frogY < carY)
				&& (carY < frogY + frogImage.getBounds().height)) {
			return true;
		} else if ((truckX < frogX)
				&& (frogX < truckX + truckImage.getBounds().width)
				&& (frogY >= truckY)
				&& (frogY < truckY + truckImage.getBounds().height)) {
			return true;
		} else if ((frogX < truckX)
				&& (truckX < frogX + frogImage.getBounds().width)
				&& (frogY < truckY)
				&& (truckY < frogY + frogImage.getBounds().height)) {
			return true;
		}

		else

			return false;
	}

	public boolean frogonLog() {
		if ((logX < frogX) && (frogX < logX + logImage.getBounds().width)
				&& (logY < frogY)
				&& (frogY < logY + logImage.getBounds().height + 15)) {
			return true;
		} else if ((Math.abs(logX - frogX) < 5) && (Math.abs(frogY - logY) < 5)) {
			return true;
		} else
			return false;
	}

	public boolean frogonLog2() {
		if ((logX2 < frogX) && (frogX < logX2 + logImage.getBounds().width)
				&& (logY2 < frogY)
				&& (frogY < logY2 + logImage.getBounds().height + 15)) {
			return true;
		} else if ((Math.abs(logX2 - frogX) < logImage.getBounds().width)
				&& (Math.abs(frogY - logY2) < logImage.getBounds().height + 15)) {
			return true;
		} else
			return false;
	}

	public boolean isInRiver() {
		if (frogY < 180) {
			return true;
		}
		return false;
	}

	public boolean eatMosquito() {

		if ((mosQuitoEated == false)
				&& (Math.abs(frogX - mosquitoX) <= 20 && Math.abs(frogY
						- mosquitoY) <= 20)) {
			return true;
		}
		else
			return false;
	}

	public boolean isReachHome() {
		if ((homeX < frogX) && (frogX < homeX + homeImage.getBounds().width)
				&& (frogY < homeY + homeImage.getBounds().height)) {
			return true;
		} else if ((Math.abs(homeX - frogX) < homeImage.getBounds().width)
				&& (Math.abs(frogY - homeY) < homeImage.getBounds().height))
			return true;
		return false;
	}

	public boolean isTimeUp() {
		if ((currentMillisTime - startMillisTime) / 1000 > frogLiveEnduration)
			return true;
		else
			return false;
	}

	/**
	 * Animates the next frame
	 */
	public void animate() {
		Rectangle rect = canvas.getClientArea();

		snakeX -= directionX * 0.7;
		logX -= directionX * 0.5;
		logX2 += directionX * 0.5;
		carX += directionX;
		truckX += directionX * 0.9;

		if (logX < logImage.getBounds().width) {
			logX = CAVAS_WIDTH - 80;
		}
		if (snakeX < snakeImage.getBounds().width) {
			snakeX = CAVAS_WIDTH - 80;
		}
		if (logX2 > rect.width - logImage.getBounds().width) {
			logX2 = 0;
		}
		if (carX > rect.width - carImage.getBounds().width) {
			carX = 20;
		}
		if (truckX > rect.width - truckImage.getBounds().width) {
			truckX = 20;
		}
		if (isFrogonLog2 == true && isFrogonLog == false) {
			frogX = logX2 + 15;
			frogY = logY2;
		}
		if (isFrogonLog == true && isFrogonLog == true) {
			frogX = logX + 15;
			frogY = logY;
		}

		// Force a redraw
		canvas.redraw();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}
